﻿using Microsoft.EntityFrameworkCore;
using SIG.Data.Mapping;
using SIGBugs.Server.Helpers;
using SIGBugs.Shared.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SIGBugs.Server.DataAccess
{
    public class BugsContext : DbContext
    {
        public BugsContext(DbContextOptions<BugsContext> options) : base(options)
        {
        }
        public virtual DbSet<User> Users { get; set; }
        public virtual DbSet<Menu> Menus { get; set; }
        public virtual DbSet<MenuCategory> MenuCategories { get; set; }
        public virtual DbSet<Role> Roles { get; set; }
        public virtual DbSet<Project> Projects { get; set; }
        public virtual DbSet<SIGBugs.Shared.Models.Task> Tasks { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {

            base.OnModelCreating(builder);
            builder.ApplyConfiguration(new UserMap());
            builder.ApplyConfiguration(new RoleMap());
            builder.ApplyConfiguration(new UserRoleMap());
            builder.ApplyConfiguration(new MenuMap());
            builder.ApplyConfiguration(new MenuCategoryMap());
            builder.ApplyConfiguration(new RoleMenuMap());

            builder.Entity<Project>()
                       .HasMany(e => e.Tasks)
                       .WithOne(e => e.Project)
                       .HasForeignKey(e => e.ProjectId)
                       .OnDelete(DeleteBehavior.Cascade);

        }
        public override int SaveChanges()
        {
            var addedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>()
              .Where(p => p.State == EntityState.Added)
              .Select(p => p.Entity);

            var modifiedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>()
              .Where(p => p.State == EntityState.Modified)
              .Select(p => p.Entity);

            var now = DateTime.UtcNow;

            foreach (var added in addedAuditedEntities)
            {
                added.CreatedDate = now;
                added.CreatedBy = Site.CurrentUserName;
            }

            foreach (var modified in modifiedAuditedEntities)
            {
                modified.UpdatedDate = now;
                modified.UpdatedBy = Site.CurrentUserName;

                base.Entry(modified).Property(x => x.CreatedBy).IsModified = false;
                base.Entry(modified).Property(x => x.CreatedDate).IsModified = false;

            }

            return base.SaveChanges();
        }

      
        public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            var addedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>()
              .Where(p => p.State == EntityState.Added)
              .Select(p => p.Entity);

            var modifiedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>()
              .Where(p => p.State == EntityState.Modified)
              .Select(p => p.Entity);

            var now = DateTime.UtcNow;

            foreach (var added in addedAuditedEntities)
            {
                added.CreatedDate = now;
                added.CreatedBy = Site.CurrentUserName;
            }

            foreach (var modified in modifiedAuditedEntities)
            {
                modified.UpdatedDate = now;
                modified.UpdatedBy = Site.CurrentUserName;

                base.Entry(modified).Property(x => x.CreatedBy).IsModified = false;
                base.Entry(modified).Property(x => x.CreatedDate).IsModified = false;

            }

            return base.SaveChangesAsync(cancellationToken);
        }
      
    }
}